#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <unistd.h>
#include <arpa/inet.h>
#include <sys/socket.h>
#include <sys/select.h>

#define MAX_CLIENTS 3
#define BUFFER_SIZE 1024

// 从字符串中取出传感器数据
void extractData(const char* input, float *temperature, float *humidity);

int main() {

    // 定义端口和IP
    char *port = "9004";
    char *ip = "0.0.0.0";

    int server_fd = socket(AF_INET, SOCK_STREAM, 0);
    struct sockaddr_in addr;
    int max_fd, activity;
    fd_set readfds;
    int client_sockets[MAX_CLIENTS] = {0};

    // 在函数里的变量，用于传递传感器数据
    float temperature, light;

    // 服务器绑定配置
    addr.sin_family = AF_INET;
    addr.sin_port = htons(atoi(port));
    addr.sin_addr.s_addr = inet_addr(ip);
    setsockopt(server_fd, SOL_SOCKET, SO_REUSEADDR, &(int){1}, sizeof(int));
    bind(server_fd, (struct sockaddr*)&addr, sizeof(addr));
    listen(server_fd, 5);

    // 主循环
    while(1) {
        FD_ZERO(&readfds);
        FD_SET(server_fd, &readfds);
        max_fd = server_fd;

        // 添加客户端socket到集合
        for (int i = 0; i < MAX_CLIENTS; i++) {
            if (client_sockets[i] > 0) {
                FD_SET(client_sockets[i], &readfds);
                if (client_sockets[i] > max_fd) max_fd = client_sockets[i];
            }
        }

        // 使用select监听
        activity = select(max_fd + 1, &readfds, NULL, NULL, NULL);
        
        // 处理新连接
        if (FD_ISSET(server_fd, &readfds)) {
            int new_socket = accept(server_fd, NULL, NULL);
            for (int i = 0; i < MAX_CLIENTS; i++) {
                if (client_sockets[i] == 0) {
                    client_sockets[i] = new_socket;
                    break;
                }
            }
        }

        // 处理客户端请求
        for (int i = 0; i < MAX_CLIENTS; i++) {
            int sd = client_sockets[i];
            if (sd > 0 && FD_ISSET(sd, &readfds)) {
                char buffer[BUFFER_SIZE] = {0};
                // 从请求中接收数据放在字符数组buffer中
                int bytes_recv = recv(sd, buffer, BUFFER_SIZE, 0);
                
                // 提取温度和湿度存到temperature和humidity
                extractData(buffer, &temperature, &light);

                if (bytes_recv <= 0) {
                    close(sd);
                    client_sockets[i] = 0;
                } else {
                    // 判断请求类型
                    if (strstr(buffer, "HTTP/1.1") || strstr(buffer, "GET") || strstr(buffer, "POST")) {
                        // 手机APP请求 (HTTP)
                        printf("HTTP Request:\n%s\n", buffer);
                        
                        // 动态生成 HTTP 响应（假设温度湿度是浮点类型）
                        char response[128];  // 根据数据范围调整缓冲区大小
                        snprintf(response, sizeof(response),
                                "HTTP/1.1 200 OK\r\n\r\n[\"当前温度：%.1f 'C\",\"当前亮度：%.0f %%\",\"待添加\"]",
                                temperature, 
                                light);
                        // char *response = "HTTP/1.1 200 OK\r\n\r\n[\"test10\",\"我是温度\",\"humi\",\"我是亮度\"]";
                        // char *response = "HTTP/1.1 200 OK\r\n\r\n[\"temperature\",\"humidity\",\"humi\",\"我是亮度\"]";
                        send(sd, response, strlen(response), 0);
                        close(sd); // HTTP短连接
                        client_sockets[i] = 0;
                    } else {
                        // STM32数据上传
                        printf("STM32 Data: %s\n", buffer);
                        // 保持连接继续接收数据
                        send(sd, "ACK", 3, 0); // 可选应答
                    }
                }
            }
        }
    }
    close(server_fd);
    return 0;
}


void extractData(const char* input, float *temperature, float *light) {
    // 使用 sscanf 从输入字符串中提取温度和百分比
    sscanf(input, "Temp: %f'C, Light: %*[^()](%f%%)", temperature, light);
}